﻿Imports Lucene.Net.Analysis
Imports Lucene.Net.Documents
Imports System
Imports System.IO
Imports System.Runtime.InteropServices
Imports System.Text
Imports Lucene.Net.Documents.Field

Namespace Aricie.DNN.Modules.LuceneSearchProvider.IFilter
    Public Class IFilterPlugin
        Implements IDocumentPlugin

        ' Methods
        Public Function Analyzer(ByVal path As String) As Analyzer Implements IDocumentPlugin.Analyzer
            Return Nothing
        End Function

        Public Function Document(ByVal path As String) As Document Implements IDocumentPlugin.Document
            Dim info As New FileInfo(path)
            Dim objDocument As New Document
            objDocument.Add(New Field("name", info.Name, Store.YES, Index.ANALYZED))
            objDocument.Add(New Field("fullname", info.FullName, Store.YES, Index.ANALYZED))
            Dim str As String = Me.getBody(path)
            objDocument.Add(New Field("body", str, Store.YES, Index.ANALYZED))
            Return objDocument
        End Function

        Public Shared Function Extract(ByVal path As String) As String
            Dim builder As New StringBuilder
            Dim o As IFilter = Nothing
            Try
                o = IFilterPlugin.loadIFilter(path)
                If (o Is Nothing) Then
                    Return String.Empty
                End If
                Dim pdwFlags As UInt32 = 0
                Dim pStat As New STAT_CHUNK
                Dim grfFlags As IFILTER_INIT = (IFILTER_INIT.APPLY_OTHER_ATTRIBUTES Or (IFILTER_INIT.APPLY_CRAWL_ATTRIBUTES Or (IFILTER_INIT.APPLY_INDEX_ATTRIBUTES Or (IFILTER_INIT.FILTER_OWNED_VALUE_OK Or (IFILTER_INIT.SEARCH_LINKS Or (IFILTER_INIT.CANON_PARAGRAPHS Or (IFILTER_INIT.CANON_SPACES Or (IFILTER_INIT.CANON_HYPHENS Or IFILTER_INIT.HARD_LINE_BREAKS))))))))
                If (o.Init(grfFlags, 0, Nothing, (pdwFlags)) <> 0) Then
                    Throw New Exception(("Problem initializing an IFilter for:" & ChrW(10) & path & " " & ChrW(10) & ChrW(10)))
                End If
                Do While (o.GetChunk(pStat) = 0)
                    If (pStat.flags = CHUNKSTATE.CHUNK_TEXT) Then
                        Dim text As IFilterReturnCodes = IFilterReturnCodes.S_OK
                        Do While ([text] = IFilterReturnCodes.S_OK)
                            Dim pcwcBuffer As UInt32 = &H10000
                            Dim buffer As New StringBuilder(CInt(pcwcBuffer))
                            [text] = CType(o.GetText((pcwcBuffer), buffer), IFilterReturnCodes)
                            If ((pcwcBuffer > 0) AndAlso (buffer.Length > 0)) Then
                                builder.Append(buffer.ToString(0, CInt(pcwcBuffer)))
                                builder.Append(" ")
                            End If
                        Loop
                    End If
                Loop
            Finally
                If (Not o Is Nothing) Then
                    Marshal.ReleaseComObject(o)
                End If
            End Try
            Return builder.ToString
        End Function

        Private Function getBody(ByVal path As String) As String
            Return IFilterPlugin.Extract(path)
        End Function

        Public Shared Function IsParseable(ByVal filename As String) As Boolean
            Return (Not IFilterPlugin.loadIFilter(filename) Is Nothing)
        End Function

        Private Shared Function loadIFilter(ByVal filename As String) As IFilter
            Dim pUnkOuter As Object = Nothing
            Dim ppIUnk As IFilter = Nothing
            If (IFilterPlugin.loadIFilter(filename, pUnkOuter, (ppIUnk)) <> 0) Then
                Return Nothing
            End If
            Return ppIUnk
        End Function

        <DllImport("query.dll", CharSet:=CharSet.Unicode)> _
        Private Shared Function LoadIFilter(ByVal pwcsPath As String, <MarshalAs(UnmanagedType.IUnknown)> ByVal pUnkOuter As Object, ByRef ppIUnk As IFilter) As Integer
        End Function


        ' Properties
        Public ReadOnly Property Description() As String Implements IDocumentPlugin.Description
            Get
                Return "Uses IFilter interface to parse the files. It relies on IFilter plugins installed in the system."
            End Get
        End Property

        Public ReadOnly Property Extensions() As String() Implements IDocumentPlugin.Extensions
            Get
                Return New String() {".*"}
            End Get
        End Property

       
    End Class
End Namespace

